package com.smart.community.user.service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.smart.community.commons.dto.SystemLogQueryDTO;
import com.smart.community.commons.entity.SystemLog;
import com.smart.community.commons.service.SystemLogService;

import lombok.extern.slf4j.Slf4j;

/**
 * 系统日志导出服务
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 */
@Slf4j
@Service
public class SystemLogExportService {
    @Autowired
    private SystemLogService systemLogService;
    
    /**
     * 导出系统日志为Excel
     * 
     * @param queryDTO 查询条件
     * @return Excel文件字节数组
     * @throws Exception 统一异常
     */
    public byte[] exportSystemLogToExcel(SystemLogQueryDTO queryDTO) throws Exception {
        log.info("开始导出系统日志，查询条件：{}", queryDTO);
        
        // 设置导出所有数据
        queryDTO.setCurrent(1);
        queryDTO.setSize(10000);
        
        // 获取数据
        List<SystemLog> logList = systemLogService.getSystemLogListForExport(queryDTO);
        
        // 创建Excel工作簿
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("系统日志");
            
            // 创建标题样式
            CellStyle headerStyle = createHeaderStyle(workbook);
            
            // 创建标题行
            Row headerRow = sheet.createRow(0);
            String[] headers = {
                "ID", "操作类型", "操作名称", "操作人", "IP地址", "请求URL", 
                "请求方法", "状态", "执行时间(ms)", "操作时间", "错误信息"
            };
            
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
                sheet.setColumnWidth(i, 15 * 256); // 设置列宽
            }
            
            // 填充数据
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            for (int i = 0; i < logList.size(); i++) {
                SystemLog log = logList.get(i);
                Row row = sheet.createRow(i + 1);
                
                row.createCell(0).setCellValue(log.getId());
                row.createCell(1).setCellValue(log.getOperationName());
                row.createCell(2).setCellValue(log.getOperationDesc());
                row.createCell(3).setCellValue(log.getUsername());
                row.createCell(4).setCellValue(log.getIpAddress());
                row.createCell(5).setCellValue(log.getRequestUrl());
                row.createCell(6).setCellValue(log.getRequestMethod());
                row.createCell(7).setCellValue(log.getStatus() == 1 ? "成功" : "失败");
                row.createCell(8).setCellValue(log.getExecutionTime());
                
                if (log.getLogTime() != null) {
                    row.createCell(9).setCellValue(log.getLogTime().format(formatter));
                }
                
                row.createCell(10).setCellValue(log.getErrorMessage());
            }
            
            // 输出到字节数组
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            
            log.info("系统日志导出完成，共导出{}条记录", logList.size());
            return outputStream.toByteArray();
            
        } catch (IOException e) {
            log.error("导出系统日志失败", e);
            throw new Exception("导出失败：" + e.getMessage());
        }
    }
    
    /**
     * 创建标题样式
     */
    private CellStyle createHeaderStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setBold(true);
        font.setFontHeightInPoints((short) 12);
        style.setFont(font);
        return style;
    }
}
